import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d.art3d import Poly3DCollection


def plot_3d_pareto_front(points, fronts):
    fig = plt.figure(figsize=(8, 6))
    ax = fig.add_subplot(111, projection='3d')

    colors = ['r', 'g', 'b', 'y', 'c', 'm']
    for i, front in enumerate(fronts):
        front_points = points[front]
        ax.scatter(front_points[:, 0], front_points[:, 1], front_points[:, 2],
                   c=colors[i % len(colors)], label=f'Front {i + 1}', s=30, edgecolors='k')

        # 连接前沿点
        if len(front_points) >= 3:  # 只有三个及以上的点才能形成三角面
            hull = Poly3DCollection([front_points], alpha=0.3, color=colors[i % len(colors)])
            ax.add_collection3d(hull)

    ax.set_xlabel('Objective 1')
    ax.set_ylabel('Objective 2')
    ax.set_zlabel('Objective 3')
    ax.view_init(elev=30, azim=45)  # 设定合适的视角
    ax.grid(True)
    plt.legend()
    plt.show()


# 生成随机数据
np.random.seed(42)
points = np.random.rand(30, 3)

# 进行快速非支配排序
fronts, _ = fast_non_dominated_sort(points)

# 绘制改进后的Pareto前沿
plot_3d_pareto_front(points, fronts)
